 #include <gsasl.h>
 #include <xpm/offline.xpm>

 void     show_error (wxWindow *, wxString, char);
 bool     xml_feed (wxString *);
 wxString rle_decode(wxString&);
 
 #define  status_invalid   -1
 #define  status_offline    0
 #define  status_available  1
 #define  status_away       2
 #define  status_busy       3

 ///////////////////////////////////////////////////////
 // Class Jabber
 ///////////////////////////////////////////////////////

 class Jabber : public wxPanel
 {
   public:

    wxBoxSizer        * j_sizer;
    wxBoxSizer        * j_szTB;
    wxBoxSizer        * j_Row1;
    wxBoxSizer        * j_Row2;
    wxBoxSizer        * j_szTool;
    wxBoxSizer        * j_szBar;
    QBitmap           * j_avatar;
    QTab              * j_status;
    QTab              * j_mail;
    QTab              * j_fPlus;
    wxArrayString     * j_friendReq;
    wxStaticText      * j_fn;
    wxStaticText      * j_fid;
    IMBuddy           * j_head;
    IMBuddy           * j_tail;
    QTab              * j_punchline;
    wxRichTextCtrl    * j_text;
    QEdit             * j_searchEdit;
    QTab              * j_search;
    Qlist             * j_contacts;
    char              * rBuf;
    bool                j_hideoffline;
    bool                g_alert;
    bool                j_hover;

    Jabber (wxWindow* parent, 
            wxWindowID id = wxID_ANY, 
            const wxPoint& pos = wxDefaultPosition, 
            const wxSize& size = wxDefaultSize, 
            long style = wxTAB_TRAVERSAL);

    ~Jabber();

    void       show_j_panel();
    void       update_roster(connection *, wxString&);
    void       process_xmpp_packet(connection *, wxString&);
    void       process_status(connection *);
    void       xmpp_status(connection *, wxString show, bool bInvisible = false);    
    void     * add_node(connection *, wxString& id, const char **status_xmp = offline_xpm);
    void     * find_node(connection *, wxString&);
    bool       check_response(wxString *);
    void       end_stream(connection *);
    bool       xml_element(wxString&, wxString&, wxString *val = 0, bool isAttribute = false);
    void       j_notify(wxString, wxString);    
    bool       j_send(connection *, wxString&);
    wxString * j_recv(connection *);
    void       update_title_bar(IMBuddy *, connection *);
    void       OnKillFocusStatusText(wxFocusEvent&);
    void       OnLeftDown(wxMouseEvent& e) { j_avatar->SetFocus(), e.Skip(); }    
    void       starOnLeftDown(wxMouseEvent& WXUNUSED(e)) { show_error(j_fPlus, "Please enter a valid host name", 2); }
    void       mailOnLeftDown(wxMouseEvent& WXUNUSED(e)) { wxLaunchDefaultBrowser("http://mail.google.com/mail"); }
 };

 typedef struct IMBuddy
 {
   wxString       * b_name;           /* friendly name like "Carla Gugino" extracted in update_roster                               */
   wxString       * b_id;             /* e-mail id in  localpart@domainpart/resourcepart extracted in update_roster                 */
   wxImage        * b_avatar;
   wxString       * b_resource;       /* resource in localpart@domainpart/resourcepart  extracted when we recieve a presence packet */
   wxString       * b_chat;           /* chat transcript                                                                            */
   int              b_i;              /* index of the item in m_contacts                                                            */
   ChatDialog     * b_tab;            /* ChatDialog for this contact                                                                */
   wxString       * b_punchline;      /* status message                                                                             */
   char             b_status;         /* -1 invited 0x00-offline, 0x01-available, 0x10-away, 0x11-busy                              */
   bool             b_flag;           /* tag, invited                                                                               */
   wxString       * b_vcard;
   wxString       * b_autoreply;
   wxString       * b_hash;           /* buddy's image hash */
   bool             b_isShown;        /* if the contact is currently shown on the UI                                                */
   wxImage        * b_snip;
   char             b_priority;
   bool             b_hidden;         /* google roster's hidden attribute "Extended Contact Attributes" */
   struct IMBuddy * next;
   connection     * b_c;
 } IMBuddy;
